import 'dart:async';
import 'dart:convert';

import 'package:intl/intl.dart';
import 'package:flutter_syt/application.dart';
import 'package:flutter_syt/datas/message_model.dart';
import 'package:flutter_syt/datas/user_info.dart';
import 'package:flutter_syt/domain/mine/service/provider_unread_msg.dart';
import 'package:flutter_syt/domain/mine/service/service_socket.dart';
import 'package:flutter_syt/root_widget.dart';
import 'package:flutter_syt/utils/utils_dlog.dart';
import 'package:provider/provider.dart';
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

/// WebSocket状态
enum SocketStatus {
  SocketStatusConnected, // 已连接
  SocketStatusFailed, // 失败
  SocketStatusClosed, // 连接关闭
  SocketStatusConnecting, // 连接中

}

///send状态
enum SendStatus {
  SendStatusSending, // 发送中
  SendStatusSendFailed, // 发送失败
  SendStatusSendDone, // 发送完成
}

enum MessageDirection {
  SEND, // 发送
  RECEIVE, // 接收
}

class WebSocketUtility {
  static var instance = WebSocketUtility._();

  WebSocketUtility._();

  IOWebSocketChannel? _webSocket; // WebSocket
  SocketStatus? _socketStatus; // socket状态
  // Timer? _heartBeat; // 心跳定时器
  // int _heartTimes = 3000; // 心跳间隔(毫秒)
  int _reconnectCount = 10; // 重连次数，默认60次
  int _reconnectTimes = 0; // 重连计数器
  Timer? _reconnectTimer; // 重连定时器

  // Function(String? error)? onError; // 连接错误回调
  // Function? onOpen; // 连接开启回调
  // Function(dynamic data)? onMessage; // 接收消息回调
  String wsUrl = '';

  String source = '';
  WebSocketDelegate? _webSocketDelegate;

  // StreamController<SocketStatus> socketStatusController = StreamController<SocketStatus>;

  setWebSocketDelegate(WebSocketDelegate delegate) {
    _webSocketDelegate = delegate;
  }

  removeWebSocketDelegate() {
    _webSocketDelegate = null;
  }

  /// 初始化WebSocket   source 客服来源（mall:商城，self:个人中心）
  void initWebSocket({
    required String wsUrl,
    required String source,
  }) async {
    this.wsUrl = wsUrl;
    // if (this.source != source) {
    //   await closeSocket();
    // }
    this.source = source;
    openSocket();
  }

  SocketStatus? getSocketStatus() {
    return _socketStatus;
  }

  /// 开启WebSocket连接
  Future openSocket({
    bool isReconnect = false,
  }) async {
    // await closeSocket();
    if (_socketStatus != SocketStatus.SocketStatusConnected &&
        this.wsUrl.isNotEmpty) {
      var storyLocal = appContext.storage.getString("storyLocal");
      var local = storyLocal ?? Intl.getCurrentLocale();
      try {
        _socketStatus = SocketStatus.SocketStatusConnecting;
        String url =
            "${this.wsUrl}?lang=$local&is_restart=${appContext.isRestartService ? 1 : 0}";
        DLog('SFDkasdfkj$url');
        _webSocket = IOWebSocketChannel.connect(Uri.parse(url),
            protocols: ["Authorization||${UserInfo.me.token}"]);
        if (isReconnect) {
          Future.delayed(Duration(milliseconds: 500), () {
            if (_socketStatus == SocketStatus.SocketStatusConnecting) {
              _socketStatus = SocketStatus.SocketStatusConnected;
              // 连接成功，重置重连计数器
              _reconnectTimes = 0;
              if (_reconnectTimer != null) {
                DLog('msg');
                _reconnectTimer?.cancel();
                _reconnectTimer = null;
              }
            }
          });
        } else {
          await Future.delayed(Duration(milliseconds: 500));
          if (_socketStatus == SocketStatus.SocketStatusConnecting) {
            _socketStatus = SocketStatus.SocketStatusConnected;
            // 连接成功，重置重连计数器
            _reconnectTimes = 0;
            if (_reconnectTimer != null) {
              DLog('msg');
              _reconnectTimer?.cancel();
              _reconnectTimer = null;
            }
          }
        }
        // DLog('WebSocket连接成功: $_SOCKET_URL');

        // socketStatusController.add(event)

      } catch (e) {}

      if (_webSocketDelegate != null) {
        // onMessage!(data);
        _webSocketDelegate!.webSocketOnConnect(true);
      }
      // if (onOpen != null) {
      //   onOpen!();
      // }
      // 接收消息
      try {
        _webSocket?.stream.listen((data) => webSocketOnMessage(data),
            onError: webSocketOnError, onDone: webSocketOnDone);
      } catch (e) {
        DLog(e);
        // closeSocket();
      }
    }
  }

  /// WebSocket接收消息回调
  webSocketOnMessage(data) {
    if (_webSocketDelegate != null) {
      // onMessage!(data);
      _webSocketDelegate!.webSocketOnMessage(data);
    }
    if (ServiceSocket.isOpen == false) {
      final ctx = navigatorKey.currentContext;
      if (ctx != null) {
        int unread = ProviderUnReadMsg().unReadNum;
        unread++;
        ProviderUnReadMsg unReadProvider =
            Provider.of<ProviderUnReadMsg>(ctx, listen: false);
        unReadProvider.unReadNum = unread;
      }
    }
  }

  /// WebSocket关闭连接回调
  webSocketOnDone() async {
    DLog('closed');
    await closeSocket();

    if (ServiceSocket.isOpen) {
      reconnect();
    }

    // reconnect();
  }

  /// WebSocket连接错误回调
  webSocketOnError(e) {
    WebSocketChannelException ex = e;
    _socketStatus = SocketStatus.SocketStatusFailed;
    // if (onError != null) {
    //   onError!(ex.message);
    // }
    if (_webSocketDelegate != null) {
      // onMessage!(data);
      _webSocketDelegate!.webSocketOnError(ex.message);
    }

    closeSocket();
  }

  /// 初始化心跳
  // void initHeartBeat() {
  //   destroyHeartBeat();
  //   _heartBeat =
  //       new Timer.periodic(Duration(milliseconds: _heartTimes), (timer) {
  //     sentHeart();
  //   });
  // }

  /// 心跳
  // void sentHeart() {
  // sendMessage('{"module": "HEART_CHECK", "message": "请求心跳"}');
  // }

  /// 销毁心跳
  // void destroyHeartBeat() {
  //   if (_heartBeat != null) {
  //     _heartBeat?.cancel();
  //     _heartBeat = null;
  //   }
  // }

  /// 关闭WebSocket
  Future closeSocket() async {
    _socketStatus = SocketStatus.SocketStatusClosed;
    if (_webSocket != null) {
      DLog('WebSocket连接关闭');
      await _webSocket?.sink.close();
      _webSocket = null;
      if (_webSocketDelegate != null) {
        _webSocketDelegate!.webSocketOnConnect(false);
      }
      await Future.delayed(Duration(milliseconds: 200));
    }
  }

  /// 发送WebSocket消息
  Future<bool> sendMessage(MessageModel message) async {
    // if (kDebugMode) {
    //   return true;
    // }
    if (_webSocket != null) {
      switch (_socketStatus) {
        case SocketStatus.SocketStatusConnected:
          DLog('发送中：' + message.toJson().toString());
          break;
        case SocketStatus.SocketStatusClosed:
          DLog('连接已关闭');
          await openSocket();
          break;
        case SocketStatus.SocketStatusFailed:
          DLog('发送失败');
          break;
        default:
          break;
      }
      if (SocketStatus.SocketStatusConnected == _socketStatus) {
        try {
          message.authorization = UserInfo.me.token;
          message.lang = appContext.storage.getString("storyLocal") ??
              Intl.getCurrentLocale();
          _webSocket?.sink.add(jsonEncode(message.toJson()));

          return true;
        } catch (e) {
          return false;
        }
      }
    } else {
      await openSocket();
    }
    // await Future.delayed(Duration(milliseconds: 100));
    return false;
  }

  /// 重连机制
  void reconnect() async {
    if (_reconnectTimes < _reconnectCount) {
      await Future.delayed(Duration(seconds: 1));
      _reconnectTimes++;
      _reconnectTimer = new Timer.periodic(Duration(seconds: 3), (timer) {
        openSocket();
      });
    } else {
      if (_reconnectTimer != null) {
        DLog('重连次数超过最大次数');
        _reconnectTimer?.cancel();
        _reconnectTimer = null;
      }
      return;
    }
  }
}

mixin  WebSocketDelegate {
  // _webSocket?.stream.listen((data) => webSocketOnMessage(data),
  //   onError: webSocketOnError, onDone: webSocketOnDone);

  void webSocketOnMessage(dynamic data);

  void webSocketOnError(dynamic error);

  // void webSocketOnDone();

  void webSocketOnConnect(bool isConnect);
}
